package com.itc.bi.handler;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.itc.bi.constant.SystemConstant;
import com.itc.bi.dto.DataSetCreateDto;
import com.itc.bi.entity.DataSetColumnEntity;
import com.itc.bi.entity.DataSetParameterEntity;
import com.itc.bi.entity.DirectDataSetEntity;
import com.itc.bi.handler.dataSet.*;
import com.itc.bi.service.DirectDataSetService;
import com.itc.common.core.exception.CheckedException;
import com.itc.common.core.exception.ServiceException;
import com.itc.common.security.utils.SecurityUtils;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

@Service
public class DataSetHandler {
    @Autowired
    DirectDataSetService dataSetService;
    @Autowired
    Database database;
    @Autowired
    FileExcel fileExcel;
    @Autowired
    PythonCode pythonCode;
    @Autowired
    SqlCode sqlCode;
    @Autowired
    RedissonClient redissonClient;

    @Transactional(rollbackFor = Exception.class)
    public void create(DataSetCreateDto dto){
        RLock lock = redissonClient.getLock("dataset:" + SecurityUtils.getUserId() + ":" + dto.getDtId());
        if (!lock.tryLock()){
            throw new ServiceException("请勿重复提交");
        }
        try {
            //检查参数是否重复
            if(!CollectionUtils.isEmpty(dto.getParams())){
                Set<String> set = new HashSet<>();
                for (DataSetParameterEntity parameter:dto.getParams()){
                    if(set.contains(parameter.getName())){
                        throw new ServiceException(String.format("参数%s重复",parameter.getName()));
                    }
                    set.add(parameter.getName());
                }

            }
            getService(dto.getType()).create(dto);
        }finally {
            lock.unlock();
        }
    }

    //数据集预览数据
    public List<Object> previewData(DataSetCreateDto dto){
        List<Object> list = getService(dto.getType()).previewData(dto);
        /*if(!CollectionUtils.isEmpty(list)){
            JSONObject data = (JSONObject)list.get(0);
            data.keySet().stream().forEach(column->{
                if(column.matches(SystemConstant.REGEX_CHINESE)){
                    throw new ServiceException("字段名不能包含中文和特殊字符");
                }
            });
        }*/
        return list;
    }
    //根据数据集ID预览数据
    public List<Object> previewData(Long id){
        DirectDataSetEntity dataSet = getDadaSet(id);
        return getService(dataSet.getType()).previewData(dataSet,1,SystemConstant.DATA_COLLECT_PREVIEW_SIZE);
    }

    //根据数据集ID预览数据
    public List<Object> list(Long id){
        DirectDataSetEntity dataSet = getDadaSet(id);
        return getService(dataSet.getType()).list(dataSet);
    }

    //根据数据集ID获取分页数据
    public IPage page(Long id,Integer pageIndex,Integer pageSize){
        DirectDataSetEntity dataSet = getDadaSet(id);
        return getService(dataSet.getType()).page(dataSet,pageIndex,pageSize);
    }

    /**
     * 数据集字段
     * @param dataSetId
     * @return
     */
    public List<DataSetColumnEntity> column(Long dataSetId){
        DirectDataSetEntity dataSet = getDadaSet(dataSetId);
        return getService(dataSet.getType()).column(dataSet);
    }

    public DataSet getService(String type){
        switch (type){
            case SystemConstant.DATA_SET_TYPE_DB:
                return database;
            case SystemConstant.DATA_SET_TYPE_SQL:
                return sqlCode;
            case SystemConstant.DATA_SET_TYPE_PYTHON:
                return pythonCode;
            case SystemConstant.DATA_SET_TYPE_EXCEL:
                return fileExcel;
            default:throw new CheckedException("类型异常");
        }
    }

    private DirectDataSetEntity getDadaSet(Long id){
        DirectDataSetEntity dataSet = dataSetService.getById(id);
        if(null == dataSet){
            throw new ServiceException("数据集不存在");
        }
        return dataSet;
    }

}
